/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;

/**
 *
 * @author Ziden
 */
// THIS WAS THE FREAKING HARDEST CLASS TO MAKE, FUCK IT HARD !!!!!!!!
// IS
// A
// MESS
public final class DumbMath {

    public static final Quaternion ROLL045  = new Quaternion().fromAngleAxis(FastMath.PI/4,   new Vector3f(0,0,1));
    public static final Quaternion ROLL090  = new Quaternion().fromAngleAxis(FastMath.PI/2,   new Vector3f(0,0,1));
    public static final Quaternion ROLL180  = new Quaternion().fromAngleAxis(FastMath.PI  ,   new Vector3f(0,0,1));
    public static final Quaternion ROLL270  = new Quaternion().fromAngleAxis(FastMath.PI*3/2, new Vector3f(0,0,1));
    public static final Quaternion YAW045n  = new Quaternion().fromAngleAxis(- FastMath.PI/4, new Vector3f(0,1,0));
    public static final Quaternion YAW045   = new Quaternion().fromAngleAxis(FastMath.PI/4,   new Vector3f(0,1,0));
    public static final Quaternion YAW090   = new Quaternion().fromAngleAxis(FastMath.PI/2,   new Vector3f(0,1,0));
    public static final Quaternion YAW180   = new Quaternion().fromAngleAxis(FastMath.PI  ,   new Vector3f(0,1,0));
    public static final Quaternion YAW270   = new Quaternion().fromAngleAxis(FastMath.PI*3/2, new Vector3f(0,1,0));
    public static final Quaternion PITCH045 = new Quaternion().fromAngleAxis(FastMath.PI/4,   new Vector3f(1,0,0));
    public static final Quaternion PITCH090 = new Quaternion().fromAngleAxis(FastMath.PI/2,   new Vector3f(1,0,0));
    public static final Quaternion PITCH180 = new Quaternion().fromAngleAxis(FastMath.PI  ,   new Vector3f(1,0,0));
    public static final Quaternion PITCH360 = new Quaternion().fromAngleAxis(FastMath.PI*2  ,   new Vector3f(1,0,0));
    public static final Quaternion PITCH270 = new Quaternion().fromAngleAxis(FastMath.PI*3/2, new Vector3f(1,0,0));
    public static final Quaternion UPRIGHT  = new Quaternion().fromAngleAxis(- FastMath.PI/2, new Vector3f(1,0,0));
    
    // need bitshift for performance 
    public static double angleDif(double firstAngle, double secondAngle) {
        double difference = secondAngle - firstAngle;
        while (difference < -180) {
            difference += 360;
        }
        while (difference > 180) {
            difference -= 360;
        }
        return difference;
    }

    public static int pixelDistance2D(float x, float y, float xx, float yy) {
        float d1, d2;
        if (x > xx) {
            d1 = x - xx;
        } else {
            d1 = xx - x;
        }
        if (y > yy) {
            d2 = y - yy;
        } else {
            d2 = yy - y;
        }
        return (int) (d1 + d2);
    }

    public static void turnTo(Node n, float angle, float axisModifier) {
        Quaternion giroPadrao = new Quaternion();
        giroPadrao.fromAngleAxis(-(FastMath.PI * angle / 180), new Vector3f(0, 1f, 0));
       // n.rotate(0f, -(FastMath.PI * angle / 180), 0f);
        n.setLocalRotation(giroPadrao);
        n.rotate(0, axisModifier, 0);
    }

    public static void turnTo(Node n, float angle) {
        Quaternion giroPadrao = new Quaternion();
        giroPadrao.fromAngleAxis(-(FastMath.PI * angle / 180), new Vector3f(0, 1f, 0));
       // n.rotate(0f, -(FastMath.PI * angle / 180), 0f);
        n.setLocalRotation(giroPadrao);
    }
    
    public static void turnToInvesrse(Node n, float angle) {
        Quaternion giroPadrao = new Quaternion();
        giroPadrao.fromAngleAxis((FastMath.PI * angle / 180), new Vector3f(0, 1f, 0));
       // n.rotate(0f, (FastMath.PI * angle / 180), 0f);
        n.setLocalRotation(giroPadrao);
    }

    static public void anglyRotate(float angle, float radius, Geometry thing, float zMod) {
        angle %= FastMath.TWO_PI;
        thing.setLocalTranslation(FastMath.cos(angle) * radius, FastMath.sin(angle) * radius, zMod);
    }

    public static void rotate(String axis, float angle, float radius, Geometry thing, float xMod, float yMod, float zMod) {
        angle %= FastMath.TWO_PI;
        if (axis.equals("Y")) {
            thing.setLocalTranslation(FastMath.cos(angle) * radius + xMod, FastMath.sin(angle) * radius + yMod, zMod);
        } else if (axis.equals("X")) {
            thing.setLocalTranslation(FastMath.cos(angle) * radius + xMod, yMod, FastMath.sin(angle) * radius + zMod);
        } else if (axis.equals("Z")) {
            thing.setLocalTranslation(FastMath.cos(angle) * radius+xMod, FastMath.sin(angle) * radius+yMod, zMod);
        }
    }
    
    public static void rotate(String axis, float angle, float radius, Node thing, float xMod, float yMod, float zMod) {
        angle %= FastMath.TWO_PI;
        if (axis.equals("Y")) {
            thing.setLocalTranslation(FastMath.cos(angle) * radius + xMod, FastMath.sin(angle) * radius + yMod, zMod);
        } else if (axis.equals("X")) {
            thing.setLocalTranslation(FastMath.cos(angle) * radius + xMod, yMod, FastMath.sin(angle) * radius + zMod);
        } else if (axis.equals("Z")) {
            thing.setLocalTranslation(FastMath.cos(angle) * radius+xMod, FastMath.sin(angle) * radius+yMod, zMod);
        }
    }

    public static float getAngle(float x, float y) {
        double dx = x;
        double dy = -y;
        double inRads = Math.atan2(dy, dx);
        if (inRads < 0) {
            inRads = Math.abs(inRads);
        } else {
            inRads = 2 * Math.PI - inRads;
        }
        return (float) Math.toDegrees(inRads);
    }
    
    public static float getAngle(float centerX, float centerY, float x, float y) {
        double dx = (x - centerX);
        double dy = -(y - centerY);
        double inRads = Math.atan2(dy, dx);
        if (inRads < 0) {
            inRads = Math.abs(inRads);
        } else {
            inRads = 2 * Math.PI - inRads;
        }
        float angulo = (float) Math.toDegrees(inRads);
        return angulo;
    }

    /*
    // need bitshift for performance 
    public static float getAngle(float centerX, float centerY, float pointX, float pointY) {
        double hipotenusa = Math.hypot((double) pixelDistance2D((int) centerX, (int) pointY, (int) pointX, (int) pointY), (double) pixelDistance2D(centerX, centerY, centerX, (int) pointY));
        double seno = pixelDistance2D(centerX, centerY, centerX, (int) pointY) / hipotenusa;
        float angulo = (float) Math.toDegrees(Math.asin(seno));

        if (centerX <= pointX) {
            angulo = 180 - angulo;
        }
        if (centerY >= pointY) {
            angulo = 360 - angulo;
        }
        return angulo;
    }
     * 
     */

    public static float getNodeAngle(Node n) {
        float headAngle = (float) Math.toDegrees(n.getLocalRotation().toAngles(null)[1]);
        if (headAngle < 0) {
            headAngle += 360;
        }
        headAngle = 360 - headAngle;
        return headAngle;
    }
}
